package com.lifang.imsoa.im.service;

import java.util.Map.Entry;
import java.util.Set;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.collections.MapUtils;
import org.glassfish.jersey.client.JerseyWebTarget;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.lifang.imsoa.im.comm.Constants;
import com.lifang.imsoa.im.comm.HTTPMethod;
import com.lifang.imsoa.im.comm.RegexUtils;
import com.lifang.imsoa.im.utils.JerseyUtils;
import com.lifang.imsoa.im.vo.EndPoints;
import com.lifang.imsoa.model.request.MessageTypeEnum;
import com.lifang.imsoa.model.request.SendMessageRequest;
import com.lifang.imsoa.model.response.BusinessException;
import com.lifang.imsoa.model.response.ErrorEnum;

/**
 * REST API Demo: 发送消息 REST API HttpClient4.3实现
 */
@Slf4j
@Service
public class MessageServiceImpl {
	private static JsonNodeFactory factory = new JsonNodeFactory(false);

    public ObjectNode sendMsg(SendMessageRequest sendMessageRequest){
        ArrayNode targetusers = factory.arrayNode();
        targetusers.add(sendMessageRequest.getToHxId());
        ObjectNode msgNode = factory.objectNode();
        MessageTypeEnum msgType = sendMessageRequest.getMessageType();
        if(MessageTypeEnum.TXT_MSG.equals(msgType)){
        	msgNode.put("msg", sendMessageRequest.getMsg());
        }else if(MessageTypeEnum.CMD_MSG.equals(msgType)){
        	msgNode.put("action", sendMessageRequest.getMsg()==null?"no_content":sendMessageRequest.getMsg());
        }else{
        	throw new BusinessException(ErrorEnum.SOA_ERROR_200006);
        }
        msgNode.put("type", msgType.getMsgType());
        //附属消息
        ObjectNode extNode = factory.objectNode();
        if(MapUtils.isNotEmpty(sendMessageRequest.getExt())){
	        Set<Entry<String, Object>> extSet = sendMessageRequest.getExt().entrySet();
	        for(Entry<String, Object> ext:extSet){
	        	extNode.put(ext.getKey(), ext.getValue()==null?"":ext.getValue().toString());
	        }
        }
		log.info("发送的ext={},extNode={}",sendMessageRequest.getExt(),extNode);
        return sendMessages("users", targetusers, msgNode, sendMessageRequest.getFromHxId(), extNode);
        
    }
    
    public static void main(String[] args) {
    	
        /**
         * 检测用户是否在线kenshinn
         */
    	/*
        String targetuserPrimaryKey = "peter";
        ObjectNode usernode = getUserStatus(targetuserPrimaryKey);
        if (null != usernode) {
            log.info("检测用户是否在线: " + usernode.toString());
        }
        */
//        /**
//         *  给用户发一条文本消息
//         */
//    	
//        String from = "jrsp25";
//        String targetTypeus = "users";
//        ObjectNode ext = factory.objectNode();
//        ArrayNode targetusers = factory.arrayNode();
////        targetusers.add("fengpei");
//        targetusers.add("jrsp24");
//        ObjectNode txtmsg = factory.objectNode();
//        txtmsg.put("msg", "测试发送消息!");
//        txtmsg.put("type","txt");
//        ObjectNode sendTxtMessageusernode = sendMessages(targetTypeus, targetusers, txtmsg, from, ext);
//        if (null != sendTxtMessageusernode) {
//            log.info("给用户发一条文本消息: " + sendTxtMessageusernode.toString());
//        }
        
       
        /**
         * 给一个群组发文本消息
         */
    	 /*
        String targetTypegr = "chatgroups";
        ArrayNode  chatgroupidsNode = (ArrayNode) EasemobChatGroups.getAllChatgroupids().path("data");
        ArrayNode targetgroup = factory.arrayNode();
        //第一个群组
       targetgroup.add(chatgroupidsNode.get(0).path("groupid").asText());
      
        //文本消息
        ObjectNode txtmsg = factory.objectNode();
        txtmsg.put("msg", "baby, I love you!");
        txtmsg.put("type","txt");
        
        String from="suchen";
        ObjectNode ext = factory.objectNode();
        ext.put("attr1","v1");
       
        ObjectNode sendTxtMessagegroupnode = sendMessages(targetTypegr, targetgroup, txtmsg, from, ext);
        if (null != sendTxtMessagegroupnode) {
            log.info("给一个群组发文本消息: " + sendTxtMessagegroupnode.toString());
        }
        */
        
        /**
         *  给用户发一条图片消息
         */
    	/*
        //File uploadImgFile = new File("/home/lynch/Pictures/24849.jpg");
    	File uploadImgFile = new File("F:/神之爱/images/girl.jpg");
        ObjectNode imgDataNode = EasemobFiles.mediaUpload(uploadImgFile);
        String imgFileUUID = imgDataNode.path("entities").get(0).path("uuid").asText();
        String shareSecret = imgDataNode.path("entities").get(0).path("share-secret").asText();
        if (null != imgDataNode) {
            log.info("上传图片文件: " + imgDataNode.toString());
        }
       // ArrayNode  chatgroupidsNode = (ArrayNode) EasemobChatGroups.getAllChatgroupids().path("data");
       
        //图片消息对象节点
        ObjectNode imgmsg = factory.objectNode();
        imgmsg.put("type","img");
        imgmsg.put("url", HTTPClientUtils.getURL(Constants.Constants.JRSP_APPKEY.replace("#", "/") + "/chatfiles/" + imgFileUUID).toString());
        imgmsg.put("filename", "24849.jpg");
        imgmsg.put("length", 10);
        imgmsg.put("secret", shareSecret);
        //String targetType = "users";//群组还是用户
        //用户或者群姐ID的数组对象节点
        ArrayNode targetusers = factory.arrayNode();
        targetusers.add("peter");
        String from="suchen";
        ObjectNode ext = factory.objectNode();
        ext.put("attr1","v1");
       ObjectNode sendimgMessageusernode = sendMessages(targetType, targetusers, imgmsg, from, ext);
        if (null != sendimgMessageusernode) {
            log.info("给一个群组发文本消息: " + sendimgMessageusernode.toString());
        }
        */
        
        /**
         *  给一个群组发图片消息
         */
    	/*
    	 //String targetType = "chatgroups";
         ArrayNode  chatgroupidsNode = (ArrayNode) EasemobChatGroups.getAllChatgroupids().path("data");
         ArrayNode targetgroup = factory.arrayNode();
         //第一个群组
        targetgroup.add(chatgroupidsNode.get(0).path("groupid").asText());

    	//--------------------
        ObjectNode sendimgMessagegroupnode = sendMessages(targetType, targetgroup, imgmsg, from, ext);
        if (null != sendimgMessagegroupnode) {
           log.info("给一个群组发文本消息: " + sendimgMessagegroupnode.toString());
        }
        */
    	
        /**
         * 给用户发一条语音消息
         */
    	
    	/*
        //String targetType="users";
    	String from="suchen";
    	ObjectNode ext = factory.objectNode();
    	ext.put("attr1","v1");
        //-------------------
       // File uploadAudioFile = new File("/home/lynch/Music/music.MP3");
        File uploadAudioFile = new File("F:/神之爱/media/mangai.mp3");
        ObjectNode audioDataNode = EasemobFiles.mediaUpload(uploadAudioFile);
        String audioFileUUID = audioDataNode.path("entities").get(0).path("uuid").asText();
        String audioFileShareSecret = audioDataNode.path("entities").get(0).path("share-secret").asText();
        if (null != audioDataNode) {
            log.info("上传语音文件: " + audioDataNode.toString());
        }
        ObjectNode audiomsg = factory.objectNode();
        audiomsg.put("type","audio");
        audiomsg.put("url", HTTPClientUtils.getURL(Constants.Constants.JRSP_APPKEY.replace("#", "/") + "/chatfiles/" + audioFileUUID).toString());
        audiomsg.put("filename", "music.MP3");
        audiomsg.put("length", 206);
        audiomsg.put("secret", audioFileShareSecret);
        ObjectNode sendaudioMessageusernode = sendMessages(targetType, targetusers, audiomsg, from, ext);
        if (null != sendaudioMessageusernode) {
            log.info("给用户发一条语音消息: " + sendaudioMessageusernode.toString());
        }
        */
    	
        /**
         *  给一个群组发语音消息
         */
    	/*
        String targetType="chatgroups";
        ArrayNode  chatgroupidsNode = (ArrayNode) EasemobChatGroups.getAllChatgroupids().path("data");
        ArrayNode targetgroup = factory.arrayNode();
        //第一个群组
       targetgroup.add(chatgroupidsNode.get(0).path("groupid").asText());
        //--------
        ObjectNode sendaudioMessagegroupnode = sendMessages(targetType, targetgroup, audiomsg, from, ext);
        if (null != sendaudioMessagegroupnode) {
            log.info("给一个群组发语音消息: " + sendaudioMessagegroupnode.toString());
        }
        */
    	
        
        /**
         *  给用户发一条透传消息
         */
        /*
    	String targetType="users";
    	ArrayNode targetusers = factory.arrayNode();
    	targetusers.add("peter");
    	String from="suchen";
    	ObjectNode ext = factory.objectNode();
    	ext.put("attr1","v1");
    	//------------
        ObjectNode cmdmsg = factory.objectNode();
        cmdmsg.put("action", "baby,i love you.");
        cmdmsg.put("type","cmd");
        ObjectNode sendcmdMessageusernode = sendMessages(targetType, targetusers, cmdmsg, from, ext);
        if (null != sendcmdMessageusernode) {
            log.info("给用户发一条透传消息: " + sendcmdMessageusernode.toString());
        }
        */
        
    }

	/**
	 * 检测用户是否在线
	 * 
	 * @param username
     *
	 * @return
	 */
	public static ObjectNode getUserStatus(String username) {
		ObjectNode objectNode = factory.objectNode();
//
//		// check appKey format
//		if (!HTTPClientUtils.match("^(?!-)[0-9a-zA-Z\\-]+#[0-9a-zA-Z]+", Constants.JRSP_APPKEY)) {
//			log.error("Bad format of Appkey: " + Constants.JRSP_APPKEY);
//			objectNode.put("message", "Bad format of Appkey");
//			return objectNode;
//		}
//
//		// check properties that must be provided
//		if (StringUtils.isEmpty(username)) {
//			log.error("You must provided a targetUserPrimaryKey .");
//			objectNode.put("message", "You must provided a targetUserPrimaryKey .");
//			return objectNode;
//		}
//
//		try {
//			URL userStatusUrl = HTTPClientUtils.getURL(Constants.JRSP_APPKEY.replace("#", "/") + "/users/"
//					+ username + "/status");
//			
//			JerseyWebTarget webTarget = EndPoints.MESSAGES_TARGET.resolveTemplate("org_name", Constants.JRSP_APPKEY.split("#")[0])
//					.resolveTemplate("app_name", Constants.JRSP_APPKEY.split("#")[1]);
//			if (null != queryStrNode && null != queryStrNode.get("ql") && !StringUtils.isEmpty(queryStrNode.get("ql").asText())) {
//				webTarget = webTarget.queryParam("ql", queryStrNode.get("ql").asText());
//			}
//			objectNode = JerseyUtils.sendRequest(webTarget, null, Constants.jrsp_credential, HTTPMethod.METHOD_POST, null);
//			
//			String userStatus = objectNode.get("data").path(username).asText();
//			if ("online".equals(userStatus)) {
//				log.error(String.format("The status of user[%s] is : [%s] .", username, userStatus));
//			} else if ("offline".equals(userStatus)) {
//				log.error(String.format("The status of user[%s] is : [%s] .", username, userStatus));
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}

		return objectNode;
	}

	/**
	 * 发送消息
	 * 
	 * @param targetType
	 *            消息投递者类型：users 用户, chatgroups 群组
	 * @param target
	 *            接收者ID 必须是数组,数组元素为用户ID或者群组ID
	 * @param msg
	 *            消息内容
	 * @param from
	 *            发送者
	 * @param ext
	 *            扩展字段
	 * 
	 * @return 请求响应
	 */
	public static ObjectNode sendMessages(String targetType, ArrayNode target, ObjectNode msg, String from,
			ObjectNode ext) {
		ObjectNode objectNode = factory.objectNode();
		// check appKey format
		if (!RegexUtils.match("^(?!-)[0-9a-zA-Z\\-]+#[0-9a-zA-Z]+", Constants.JRSP_APPKEY)) {
			log.error("Bad format of Appkey: " + Constants.JRSP_APPKEY);
			objectNode.put("message", "Bad format of Appkey");
			return objectNode;
		}
		// check properties that must be provided
		if (!("users".equals(targetType) || "chatgroups".equals(targetType))) {
			log.error("TargetType must be users or chatgroups .");
			objectNode.put("message", "TargetType must be users or chatgroups .");
			return objectNode;
		}
		// 构造消息体
		ObjectNode dataNode = factory.objectNode();
		dataNode.put("target_type", targetType);
		dataNode.put("target", target);
		dataNode.put("msg", msg);
		dataNode.put("from", from);
		dataNode.put("ext", ext);

		JerseyWebTarget webTarget = EndPoints.MESSAGES_TARGET.resolveTemplate("org_name", Constants.JRSP_APPKEY.split("#")[0])
				.resolveTemplate("app_name", Constants.JRSP_APPKEY.split("#")[1]);
		return JerseyUtils.sendRequest(webTarget, dataNode, Constants.jrsp_credential, HTTPMethod.METHOD_POST, null);
	}

}
